package iterator;

import global.GlobalConst;
import heap.Heapfile;
import heap.Tuple;

public class OBuf extends java.lang.Object implements GlobalConst {

	private byte[][] bufs;
	private int n_pages;
	private int tSize;
	private Heapfile temp_fd;
	private boolean isBuffer = false;

	private boolean isDirty;
	private int currentPageID;
	private int tupplesAtPage;
	private int tupplesAtBuffer;
	private long writtenRecoreds;

	private int numberOfTupplesAtBuffer;
	private int numberOfTupplesAtPage;

	public OBuf() {

	}

	public void init(byte[][] bufs, int n_pages, int tSize, Heapfile temp_fd,
			boolean buffer) {
		this.bufs = bufs;
		this.n_pages = n_pages;
		this.tSize = tSize;
		this.temp_fd = temp_fd;
		isBuffer = buffer;

		isDirty = false;
		currentPageID = 0;
		tupplesAtPage = 0;
		tupplesAtBuffer = 0;
		writtenRecoreds = 0;

		numberOfTupplesAtPage = MINIBASE_PAGESIZE / tSize;
		numberOfTupplesAtBuffer = numberOfTupplesAtPage * n_pages;
	}

	public Tuple Put(Tuple buf) throws java.io.IOException, java.lang.Exception {
		byte[] data = buf.getTupleByteArray();
		System.arraycopy(data, 0, bufs[currentPageID], tSize * tupplesAtPage,
				tSize);
		Tuple currenTuple = new Tuple(bufs[currentPageID], tupplesAtPage* tSize, tSize);
		tupplesAtPage++;
		writtenRecoreds++;
		tupplesAtBuffer++;
		isDirty = true;
		if (tupplesAtBuffer == numberOfTupplesAtBuffer) {
			flush();
			tupplesAtPage = 0;
			tupplesAtBuffer = 0;
			currentPageID = 0;
		} else if (tupplesAtPage == numberOfTupplesAtPage) {
			tupplesAtPage = 0;
			currentPageID++;
		}
		return currenTuple;
	}

	public long flush() throws java.io.IOException, java.lang.Exception {
		if (isDirty) {
			byte[] data = new byte[tSize];
			for (int i = 0; i <= currentPageID; i++) {
				if (i == currentPageID) {
					for (int j = 0; j < tupplesAtPage; j++) {
						System.arraycopy(bufs[i], tSize * j, data, 0, tSize);
						try {
							temp_fd.insertRecord(data);
						} catch (Exception e) {
							throw e;
						}
					}
				} else {
					for (int j = 0; j < numberOfTupplesAtPage; j++) {
						System.arraycopy(bufs[i], tSize * j, data, 0, tSize);
						try {
							temp_fd.insertRecord(data);
						} catch (Exception e) {
							throw e;
						}
					}
				}
			}
		}
		return writtenRecoreds;
	}

}
